package com.ccrfid.rmc6.service.device;

import com.ccrfid.rmc6.appconfig.exception.pojo.AppException;
import com.ccrfid.rmc6.appconfig.exception.pojo.CustomErrors;
import com.ccrfid.rmc6.entity.device.NetreaderEntity;
import com.ccrfid.rmc6.repository.device.NetreaderRepository;
import com.ccrfid.rmc6.repository.search.SearchCriteria;
import com.ccrfid.rmc6.resource.device.pojo.FloorPos;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import javax.ws.rs.core.Response;
import java.util.List;

@Service
@Transactional
public class NetreaderServiceImpl implements NetreaderService {
    private static final Logger logger = LoggerFactory.getLogger(NetreaderServiceImpl.class);
    @Autowired
    private NetreaderRepository netreaderRepository;

    @Override
    public Page<NetreaderEntity> getNetreaderInfoPage(SearchCriteria criteria, Pageable pageable) {
        Page<NetreaderEntity> page = netreaderRepository.search(criteria, pageable);
        return page;
    }

    @Override
    public List<NetreaderEntity> getNetreaderList(SearchCriteria criteria, Sort sort) {
        return netreaderRepository.search(criteria, sort);
    }

    @Override
    public NetreaderEntity getNetreader(Long readerId) {
        return netreaderRepository.getById(readerId);
    }

    @Override
    public NetreaderEntity createNetreader(NetreaderEntity entity) throws AppException {
        checkParamForCreate(entity);
        return netreaderRepository.save(entity);
    }

    private void checkParamForCreate(NetreaderEntity entity) throws AppException {
        if (netreaderRepository.existsByIp(entity.getIp())) {
            throw new AppException(Response.Status.CONFLICT.getStatusCode(),
                    CustomErrors.ip_conflict.getCode(), CustomErrors.ip_conflict.getReason(), "");
        }
        if (netreaderRepository.existsByReaderNumber(entity.getReaderNumber())) {
            throw new AppException(Response.Status.CONFLICT.getStatusCode(),
                    CustomErrors.reader_address_conflict.getCode(), CustomErrors.reader_address_conflict.getReason(), "");
        }
    }

    @Override
    public NetreaderEntity updateNetreader(Long readerId, NetreaderEntity entity) throws AppException {
        checkParamForUpdate(readerId, entity);
        return netreaderRepository.save(entity);
    }

    @Override
    public void updateOnlineStatus(Integer readerNumber, Integer onlineStatus) {
        NetreaderEntity netreaderEntity = netreaderRepository.getByReaderNumber(readerNumber);
        if (netreaderEntity != null) {
            netreaderEntity.setOnlineStatus(onlineStatus);
            netreaderRepository.save(netreaderEntity);
        }
    }

    private void checkParamForUpdate(Long readerId, NetreaderEntity entity) throws AppException {
        if (!readerId.equals(entity.getId())) {
            throw new AppException(Response.Status.BAD_REQUEST.getStatusCode(),
                    CustomErrors.different_args.getCode(), CustomErrors.different_args.getReason(), "");
        }
        if (!netreaderRepository.existsById(readerId)) {
            throw new AppException(Response.Status.NOT_FOUND.getStatusCode(),
                    CustomErrors.resource_not_found.getCode(), CustomErrors.resource_not_found.getReason(), "");
        }
        if (netreaderRepository.existsByIpAndIdNot(entity.getIp(), readerId)) {
            throw new AppException(Response.Status.CONFLICT.getStatusCode(),
                    CustomErrors.ip_conflict.getCode(), CustomErrors.ip_conflict.getReason(), "");
        }
        if (netreaderRepository.existsByReaderNumberAndIdNot(entity.getReaderNumber(), readerId)) {
            throw new AppException(Response.Status.CONFLICT.getStatusCode(),
                    CustomErrors.reader_address_conflict.getCode(), CustomErrors.reader_address_conflict.getReason(), "");
        }
    }

    @Override
    public NetreaderEntity updatePosition(Long readerId, FloorPos floorPos) throws AppException {
        if (!netreaderRepository.existsById(readerId)) {
            throw new AppException(Response.Status.NOT_FOUND.getStatusCode(),
                    CustomErrors.resource_not_found.getCode(), CustomErrors.resource_not_found.getReason(), "");
        }
        NetreaderEntity entity = netreaderRepository.getById(readerId);
        if (entity != null) {
            entity.setFloorNumber(floorPos.getFloorNumber());
            entity.setPos(floorPos.getPos());
            netreaderRepository.save(entity);
        }
        return entity;
    }

    @Override
    public Boolean deletePosition(Long readerId) throws AppException {
        if (!netreaderRepository.existsById(readerId)) {
            throw new AppException(Response.Status.NOT_FOUND.getStatusCode(),
                    CustomErrors.resource_not_found.getCode(), CustomErrors.resource_not_found.getReason(), "");
        }
        NetreaderEntity entity = netreaderRepository.getById(readerId);
        if (entity != null) {
            entity.setFloorNumber(null);
            entity.setPos(null);
            netreaderRepository.save(entity);
        }
        return true;
    }

    @Override
    public int deleteNetreadersInfo(List<Long> idList) {
        int count = 0;
        for (Long id : idList) {
            if (netreaderRepository.existsById(id)) {
                count++;
            }
        }
        if (count > 0) {
            //delete entity
            netreaderRepository.deleteByIdIn(idList);
        }
        return 0;
    }
}
